from flask import abort, jsonify
from flask import current_app
from flask import g
from flask import request
from flask import session
from info.utlis.common import login_user_data
from info import constants, db
from info.models import User, News, Category, Comment, CommentLike
from info.utlis.response_code import RET
from . import news_bp
from flask import render_template

@news_bp.route('/comment_like')
@login_user_data
def comment_like():
    '''评论的点赞．取消点赞'''
    params_dict = request.json
    news_id = params_dict.get('news_id')
    comment_id = params_dict.get('comment_id')
    action = params_dict.get('action')
    user = g.user

#     非空判断
    if not all([news_id, comment_id, action]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不足")

    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")

    if action not in['add','remove']:
        return jsonify(errno=RET.PARAMERR, errmsg="action数据不足")

    try:
        comment = Comment.query.get(comment_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询评论数据异常")

    if not comment:
        return jsonify(errno=RET.NODATA, errmsg="评论数据存在")

    # 3.2 跟action去完成点赞或者取消点赞的功能
    if action == 'add':
        # 3.3 点赞：根据 user_id和comment_id 查询CommentLike是否存在
        # 3.3.1 CommentLike存在：表示用户点过这条评论
        comment_like = Comment.query.filter(CommentLike.user_id == user.id).first()

        if not comment_like:
            # 3.3.2 CommentLike不存在：新建CommentLike模型对象最终保存回数据库
            comment_like = CommentLike()
            comment_like.user_id = user.id
            comment_like.comment_id = comment_id
            db.session.add(comment_like)
            # 3.3.3 记录comment模型的点赞数量（+1）
            comment.like_count +=1
        else:
             # 3.4 取消点赞：根据 user_id和comment_id 查询CommentLike是否存在
             # 只有comment_like对象存在的时候才能去取消点赞
            comment_like = CommentLike.query.filter(CommentLike.user_id == user.id,CommentLike.comment_id == comment_id).first()

            if comment_like:
                # CommentLike存在才取消点赞
                db.session.delete(comment_like)
                comment.like_count -=1

            # 将上述对于数据库模型对象的修改提交到数据库
        try:
            db.session.commit()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg="保存数据异常")

        return jsonify(errno=RET.OK, errmsg="OK")


@news_bp.route('/news_comment', methods = ['POST'])
@login_user_data
def news_comment():
    '''评论接口（主评论，子评论）'''
    params_dict = request.json
    news_id = params_dict.get('news_id')
    comment = params_dict.get('comment')
    parent_id = params_dict.get('parent_id')
    user = g.user

    # 2.参数校验
    # 2.1　非空判断
    if not all([news_id, comment]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不足")

    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")

    # 3.1　根据新闻id查询新闻（新闻存在才能去评论）
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询新闻对象异常")
    # 如果news是空的话，就不存在数据
    if not news:
        return jsonify(errno=RET.NODATA, errmsg="新闻不存在")

    # 3.2 创建评论模型，给各个属性赋值
    comment_obj = Comment()
    comment_obj.user_id = user.id
    comment_obj.news_id = news_id
    comment_obj.content = comment

    # 3.3 判断parent_id是否有值
    if parent_id:
        # parent_id 有值表示是子评论
        comment_obj.parent_id = parent_id
    try:
        db.session.add(comment_obj)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="保存评论对象到数据库异常")
    # 4.组织响应对象
    return jsonify(errno=RET.OK, errmsg="评论成功",data = comment_obj.to_dict())



# 127.0.0.1:5000/news/news_collect post
@news_bp.route('/news_collect',methods = ['POST'])
@login_user_data
def news_collect():
    '''收藏和取消收藏接口'''
    # 1．获取参数
    params_dict = request.json
    news_id = params_dict.get('news_id')
    action =params_dict.get('action')
    #  获取新闻数据
    user = g.user
    # ２．校验参数
    if not all([news_id, action]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不足")

    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")

    if action not in ['collect','cancel_collect']:
        return jsonify(errno=RET.PARAMERR, errmsg="参数填写错误")

    # 3 逻辑处理
    # 3.1　根据新闻id查询该新闻
    news = None
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询新闻数据异常")
    if not news:
        return jsonify(errno=RET.NODATA, errmsg="新闻不存在")

    # 3.2 收藏：将新闻添加到collect_news中
    if action == 'collect':
        user.collection_news.append(news)
    else:
        # 3.3 取消收藏
        user.collection_news.remove(news)

    # 3.4　提交修改操作到数据库中

    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="提交数据到数据库异常")

    # 4.返回值处理
    return jsonify(errno=RET.OK, errmsg="OK ")



# 127.0.0.1:5000/new/2
@news_bp.route('/<int:news_id>')
@login_user_data
def news_detail(news_id):
    '''展示新闻详情'''
    # －－－－－1.获取新闻数据－－－－－－－
    user = g.user

    # －－－－－2.查询新闻的点击排行数据－－－－－－－
    news_model_list = []
    try:
        news_model_list = News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)
        # 切记不能返回return 否则首页都渲染不了啦，只需要返回一个None的数据即可


    # 2. 将模型列表转换成字典列表
    news_dict_list = []
    for news in news_model_list if news_model_list else []:
        # 获取到new对象调用to_dict方法将对象转换成字典，再添加到news_dict_list中
        news_dict_list.append(news.to_dict())

    # －－－－－3.查询新闻的详情数据－－－－－－－
    news = None  # type: News
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)

    if not news:
        abort(404)
    #     浏览量自增
    news.clicks +=1

    # 将修改的模型提交到数据库
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        abort(404)

    # －－－－－4.查询用户是否收藏过该新闻－－－－－－－

    is_collected = False
    if user:
        if news in user.collection_news:
        # news在用户收藏的新闻列表内
            is_collected = True

    # －－－－－5.查询新闻的评论数据－－－－－－－
    comments = []
    try:
        comments = Comment.query.filter(Comment.news_id == news_id).order_by(Comment.create_time.desc()).all()
    except Exception as e:
        current_app.logger.error(e)
    #  模型列表转字典列表

    comment_dict_list = []
    for comment in comments if comments else []:
        comment = comment.to_dict()
        comment_dict_list.append(comment)




    data = {
        "news": news.to_dict(),
        "user_info": user.to_dict() if user else None,
        "newsClicksList": news_dict_list,
        'is_collected': is_collected,
        'comments':comment_dict_list

    }

    return render_template("news/detail.html", data=data)

